home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Nebula 2
/
Nebula Two.iso
/
SourceCode
/
GameKit
/
gamekit-1
/
GKSound.m
< prev
next >
Wrap
Text File
|
1995-06-12
|
4KB
|
129 lines
// GKSound: se the header file for info on it's use.
#import <gamekit/gamekit.h>
#import <daymisckit/daymisckit.h>
#import <sound/sound.h>
@implementation GKSound
- setPlayStream:aStream { streamGroup = aStream; return self; }
- _initGKSound
{
if (!now) now = [[DAYTime alloc] init];
if (!timeToPlay) timeToPlay = [[DAYTime alloc] init];
if (!nextPlay) nextPlay = [[DAYTime alloc] initWithCurrentTime];
return self;
}
// overridden init methods: (to assure that _initGKSound is called)
- initFromSoundfile:(const char *)filename
{
id ret = [super initFromSoundfile:filename];
[self _initGKSound];
[self convert];
return ret;
}
- initFromSection:(const char *)sectionName
{
id ret = [super initFromSection:sectionName];
[self _initGKSound];
[self convert];
return ret;
}
- initFromPasteboard:(Pasteboard *)thePboard
{
id ret = [super initFromPasteboard:thePboard];
[self _initGKSound];
[self convert];
return ret;
}
// the new methods:
- setPercentToPlay:(double)percent // how much to play before next play
{
SNDSoundStruct *mySoundData = [self soundStruct];
// assuming that we're 16bit 22.050kHz mono sound
long timeOnStream = (mySoundData->dataSize / 2) * 45.3514739229;
double usecToPlay = timeOnStream * percent;
[[timeToPlay init] addMicroseconds:(timeOnStream - usecToPlay)];
#ifdef NOISYDEBUG
fprintf(stderr, "GKSound: Play %f percent out of %ld usec (%f usec).\n",
percent, timeOnStream, usecToPlay);
fprintf(stderr, "GKSound: Play when %s (%d) left to go.\n\n",
[timeToPlay stringValue], [timeToPlay microsecond]);
#endif
return self;
}
- setTimeToPlay:aTime // how long to play sound before next play
{ // aTime says how long after start of sound play we must wait.
// we need to find how soon before the sound ends we can start:
SNDSoundStruct *mySoundData = [self soundStruct];
// assuming that we're 16bit 22.050kHz mono sound
long timeOnStream = (mySoundData->dataSize / 2) * 45.3514739229;
[[[timeToPlay init] addMicroseconds:timeOnStream] subtractTime:aTime];
#ifdef NOISYDEBUG
fprintf(stderr, "GKSound: Play after %s (%d).\n",
[aTime stringValue], [aTime microsecond]);
fprintf(stderr, "GKSound: Play when %s (%d) left to go.\n\n",
[timeToPlay stringValue], [timeToPlay microsecond]);
#endif
return self;
}
- convert
{
int err;
if (err = [self convertToFormat:SND_FORMAT_LINEAR_16
samplingRate:SND_RATE_LOW channelCount:1]) {
fprintf(stderr, "%s: GKSound convert error %s\n",
[NXApp appName], SNDSoundError(err));
}
return self;
}
- (int)play // overridden playback method
{
id temp; // a DAYTime that says when the sound will finish playing.
// check to see if we can be played or not
[now initWithCurrentTime];
#ifdef NOISYDEBUG
fprintf(stderr, "GKSound: Now is: %s (%d)\n", [now stringValue],
[now microsecond]);
fprintf(stderr, "GKSound: Next play at: %s (%d) -- %s\n",
[nextPlay stringValue], [nextPlay microsecond],
([nextPlay isAfter:now] ? "Don't play it." : "Play it."));
#endif
if ([nextPlay isAfter:now])
return SND_ERR_NONE; // not time yet: ignore the play
// do the actual playback:
if (delegate && [delegate respondsTo:@selector(willPlay:)])
[delegate willPlay:self]; // we can do this one.
temp = [streamGroup playSoundStruct:[self soundStruct]];
// I suppose that if you _really_ need the didPlay, you could set a
// timed entry to go off when the sound is supposed to finish. *****
// or hack the GKSoundStream to return/forward the delegate method
// -soundStream:didCompleteBuffer: which would do the trick (if you
// have it track the tags; right now it forgets them)
// Calculate when it will be OK to fire off a new sound:
[nextPlay copyTimeFrom:temp];
[nextPlay subtractTime:timeToPlay];
#ifdef NOISYDEBUG
fprintf(stderr, "GKSound: Sound should end at: %s (%d)\n",
[temp stringValue], [temp microsecond]);
fprintf(stderr,
"GKSound: Subtract %s (%d) and start next sound at %s (%d)\n\n",
[timeToPlay stringValue], [timeToPlay microsecond],
[nextPlay stringValue], [nextPlay microsecond]);
#endif
return SND_ERR_NONE;
}
@end